<HTML>
<HEAD>
<TITLE>mr_ipc</TITLE>
</HEAD>
<BODY>
<H1>mr_ipc</H1>
<P>
<H2>Bibliothek</H2>
<P>
<TABLE BORDER="1">
<TR><TH>Library</TH><TD>mr_ipc</TD></TR>
<TR><TH>Projekt</TH><TD>libs/mr_ipc</TD></TR>
</TABLE>
<P>
<H2>Benutzung</H2>
<P>
Jedes Programm kann nach Einf&uuml;gen der folgenden Include-Anweisung auf die
Definitionen der Bibliothek zugreifen:
<PRE>#include <mr_ipc.h></PRE>
<P>
Dazu mu&szlig; das Include Verzeichnis der lokalen Libraries dem Compiler mit
der folgenden Anweisung bekannt gemacht werden:
<PRE>-I$(INCLUDE_PATH)</PRE>
mit einer geeigneten Definition von <VAR>$INCLUDE_PATH</VAR>
<P>
In der Linker Anweisung mu&szlig; die Library mit der folgenen Anweisung mit
gelinkt werden:
<PRE>-lmr_ipc</PRE>
<P>
Dazu mu&szlig; das Lib Verzeichnis der lokalen Libraries dem Linker mit
der folgenden Anweisung bekannt gemacht werden:
<PRE>-L$(LIB_PATH)</PRE>
mit einer geeigneten Definition von <VAR>$LIB_PATH</VAR>
<P>
<H2>Beschreibung</H2>
<P>
Die Bibliothek <VAR>mr_ipc</VAR> fa&szlig;t Datentypen und Funktionen
zusammen, die f&uuml;r die Kommunikation der Clients mit der
<VAR>drehscheibe</VAR> n&ouml;tig sind. Dies umfa&szlig;t zum einen den
Datentyp, der zwischen den Programmen &uuml;bertragen wird, als auch
Funktionen, um eine Verbbindung zu dem Server zu &ouml;ffnen und Daten zu
&uuml;bertragen. Der Name leitet sich von <B>I</B>nter <B>P</B>rocess
<B>C</B>ommunication ab.
<P>
<H2>Definitionen</H2>
<P>
<H3>Konstanten</H3>
<P>
<H4>Konstanten f&uuml;r Error Codes der Sende- und Empfangsfunktionen</H4>
<P>
<PRE>#define MR_IPC_RCV_ERROR  -1
#define MR_IPC_RCV_CLOSED 0
#define MR_IPC_RCV_OK     1</PRE>
<P>
<H4>Objectnamen f&uuml;r JSON Kommandos</H4>
<P>
<PRE>#define MR_IPC_JSON_OBJECT_CMD "cmd"
#define MR_IPC_JSON_OBJECT_ADDR      "addr"
#define MR_IPC_JSON_OBJECT_DIRECTION "direction"
#define MR_IPC_JSON_OBJECT_SPEED     "speed"</PRE>
<P>
<H4>Parameter f&uuml;r das JSON Object <VAR>"cmd"</VAR></H4>
<P>
<PRE>#define MR_IPC_JSON_CMD_NULL       "null"
#define MR_IPC_JSON_CMD_LOCOMOTIVE "locomotive"</PRE>
<P>
<H3>Datentypen</H3>
<P>
<TABLE BORDER="1">
<TR>
<TH>MrIpcCmdType</TH>
<TD>Dies ist der Datentyp, der zwischen Clients und <VAR>drehscheibe</VAR>
&uuml;bertragen wird.
<P>
<TABLE BORDER="1">
<TR>
<TH>Rendered</TH>
<TD>enth&auml;lt das JSON Komamndo nachdem es mit der JSON lib erzeugt wurde.
Der Speicher wird durch das Rendern angelegt und mu&szlig; selbst freiggeben
werden, wenn die Struktur nicht merh ben&ouml;tigt wird. Die kann durch Aufurf
der Funktion <VAR>MrIpcClear()</VAR> geschehen. Wurde die Struktur dynamisch
mit <VAR>MrIpcCreate()</VAR> erzeugt, so &uuml;bernimmt <VAR>MrIpcDestroy</VAR>
das Freigeben.
</TD>
</TR>
</TABLE>
</TD></TR>
<TR>
<TH>DirectionType</TH>
<TD>legt die Werte f&uuml;r die Fahrtrichtung fest.
<TABLE BORDER="1">
<TR><TH>Forward</TH><TD>Wert f&uuml;r Vorw&auml;rts</TD></TR>
<TR><TH>Backward</TH><TD>Wert f&uuml;r R&uuml;ckw&auml;rts</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TH>MrIpcCommandValue</TH>
<TD>Returnwerte f&uuml;r <VAR>MrIpcCmdGetCmd()</VAR>
<TABLE BORDER="1">
<TR><TH>MrIpcCmdNull</TH><TD>Leeres Kommando (auch R&uuml;ckgabe bei Fehler)</TD></TR>
<TR><TH>MrIpcCmdLocomotive</TH><TD>Kommando zum Steuern einer Lokomotive</TD></TR>
</TABLE></TD>
</TR>
</TABLE>
<P>
<H3>Makros</H3>
<P>
<TABLE BORDER="1">
<TR>
<TR>
<TH NOWRAP>MrIpcClose(socket)</TH>
<TD>Dieses Makro schlie&szlig;t den Socket zur <VAR>drehscheibe</VAR>. Das
Makro dient eher dazu, eine Symetrie bei den Funktionen herzustellen.
<VAR>MrIpcConnect()</VAR> &ouml;ffnet die Verbindung und <VAR>MrIpcClose</VAR>
schlie&szlig;t sie wieder.</TD>
</TR>
</TABLE>
<P>
<H3>Funktionen</H3>
<P>
<TABLE BORDER="1">
<TR>
<TH NOWRAP>MrIpcCmdType *MrIpcCreate(void);</TH>
<TD>Diese Funktion erzeugt eine <VAR>MrIpcCmdType</VAR> Struktur. Da im
Wesentlichen ein Aufruf von <VAR>malloc()</VAR> dahinter steckt, kann die
Struktur auch statisch angelgt werden. Wir die Struktur sehr oft ben&ouml;tigt
und erzeugt, empfiehlt es sich sowieso, die Struktur nicht &uuml;ber einen
<VAR>malloc()</VAR> Aufruf anzulegen, sondern einfach als AUTO-Variable einer
Funktion zu deklarieren:
<PRE>void MyFunc(void)
{  MrIpcCmdType Command;</PRE></TD>
</TR>
<TR>
<TH NOWRAP>void MrIpcDestroy(MrIpcCmdType *Data);</TH>
<TD>Diese Funktion gibt eine dynamisch angelegte <VAR>MrIpcCmdType</VAR>
Struktur wieder frei.</TD>
<TR>
<TH NOWRAP>void MrIpcInit(MrIpcCmdType *Data);</TH>
<TD>Diese Funktion initialisiert eine <VAR>MrIpcCmdType</VAR> Struktur. Wird
die Struktur als AUTO-Variable angelegt, mu&szlig; sie mit dieser Funktion
initialisiert werden, damit sie definierte Werte enth&auml;lt!
<PRE>void MyFunc(void)
{  MrIpcCmdType Command;

   MrIpcInit(&Command);</PRE></TD>
</TR>
<TR>
<TH NOWRAP>void MrIpcClear(MrIpcCmdType *Data);</TH>
<TD>Diese Funktion r&auml;umt eine <VAR>MrIpcCmdType</VAR> Struktur nach der
Benutzung wieder auf und mu&szlig; als letztes aufgerufen werden, wenn die
Struktur als AUTO-Variable angelegt wurde.
<PRE>void MyFunc(void)
{  MrIpcCmdType Command;

   MrIpcInit(&Command);
...
   MrIpcClear(&Command);
}</PRE></TD>
</TR>
<TR>
<TH NOWRAP>int MrIpcConnect(char *IpAddr, int Port);</TH>
<TD>Diese Funktion stellt eine Verbindung eines Clients zu dem Server
<VAR>drehscheibe</VAR> her.
<TABLE BORDER="1">
<TR><TH NOWRAP>char *IpAddr</TH><TD>IP Adresse des Servers</TD></TR>
<TR><TH NOWRAP>int Port</TH><TD>Port, auf dem der Server lauscht</TD></TR>
<TR><TH NOWRAP>RETURNWERT:</TH><TD>Socket der neuen Verbindung, &lt;0 im Fehlerfall</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH NOWRAP>int MrIpcStartServer(char *IpAddr, int Port);</TH>
<TD>Diese Funktion startet die Netzwerkverbindung, &uuml;ber den der Server
<VAR>drehscheibe</VAR> eine eingehende Verbindung bekommen kann.
<TABLE BORDER="1">
<TR><TH NOWRAP>char *IpAddr</TH><TD>IP Adresse, auf der dr Server auf Verbindungen wartet</TD></TR>
<TR><TH NOWRAP>int Port</TH><TD>Port, auf der der Server auf Verbindungen wartet</TD></TR>
<TR><TH NOWRAP>RETURNWERT:</TH><TD>Socket des Servers, &lt;0 im Fehlerfall</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH NOWRAP>int MrIpcAccept(int ServerSock);</TH>
<TD>Diese Funktion akzeptiert eine neue Verbindung eines Clients zu dem Server
<VAR>drehscheibe</VAR>.
<TABLE BORDER="1">
<TR><TH NOWRAP>int ServerSock</TH><TD>Socket, auf dem der Server auf neue Verbindungen wartet</TD></TR>
<TR><TH NOWRAP>RETURNWERT:</TH><TD>Socket des Datenverbindung zum Client, &lt;0 im Fehlerfall</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH>int MrIpcSend(int socket, MrIpcCmdType *Data);</TH>
<TD>Diese Funktion versendet ein Datenpaket <VAR>MrIpcCmdType</VAR>
<TABLE BORDER="1">
<TR><TH NOWRAP>int socket</TH><TD>Socket, &uuml;ber den die Daten verschickt werden sollen</TD></TR>
<TR><TH NOWRAP>MrIpcCmdType *Data);</TH><TD>Zu versendende Daten</TD></TR>
<TR><TH NOWRAP>RETURNWERT:</TH><TD>MR_IPC_RCV_ERROR, MR_IPC_RCV_CLOSED oder MR_IPC_RCV_OK</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH>int MrIpcRecv(int socket, MrIpcCmdType *Data);</TH>
<TD>Diese Funktion empf&auml;ngt ein Datenpaket <VAR>MrIpcCmdType</VAR>
<TABLE BORDER="1">
<TR><TH NOWRAP>int socket</TH><TD>Socket, &uuml;ber den die Daten empfangen werden sollen</TD></TR>
<TR><TH NOWRAP>MrIpcCmdType *Data);</TH><TD>Zeiger auf Speicher, wohin die empfangenen Daten gelesen werden sollen</TD></TR>
<TR><TH NOWRAP>RETURNWERT:</TH><TD>MR_IPC_RCV_ERROR, MR_IPC_RCV_CLOSED oder MR_IPC_RCV_OK</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH NOWRAP>void MrIpcCmdSetNull(MrIpcCmdType *Data);</TH>
<TD>Diese Funktion codiert ein leeres Kommando.</TD>
</TR>
<TR>
<TH>void MrIpcCmdSetLocomotive(MrIpcCmdType *Data, unsigned Addr, DirectionType Direction, unsigned Speed);</TH>
<TD>Diese Funktion kodiert einen Befehl zum Steuern einer Lokomotive.
<TABLE BORDER="1">
<TR><TH NOWRAP>MrIpcCmdType *Data</TH><TD>Zeiger auf die Kommando Struktur</TD></TR>
<TR><TH NOWRAP>unsigned Addr</TH><TD>Adresse der Lokomotive</TD></TR>
<TR><TH NOWRAP>DirectionType Direction</TH><TD>Fahrtrichtung</TD></TR>
<TR><TH NOWRAP>unsigned Speed</TH><TD>Geschwindigkeit</TD></TR>
</TABLE></TD>
<TR>
<TH>int MrIpcCmdGetCmd(MrIpcCmdType *Data);</TH>
<TD>Diese Funktion liefert das empfangene Kommando
<TABLE BORDER="1">
<TR><TH NOWRAP>RETURNWERT:</TH><TD>Kommando wie <VAR>MR_IPC_CMD_NULL</VAR>, ...</TD></TR>
</TABLE></TD>
</TR>
<TR>
<TH>void MrIpcCmdGetLocomotive(MrIpcCmdType *Data, unsigned *Addr, DirectionType *Direction, unsigned *Speed);</TH>
<TD>Diese Funktion dekodiert (liefert die Parameter) einen Befehls zum Steuern
einer Lokomotive.
<TABLE BORDER="1">
<TR><TH NOWRAP>MrIpcCmdType *Data</TH><TD>Zeiger auf die Kommando Struktur</TD></TR>
<TR><TH NOWRAP>unsigned *Addr</TH><TD>Zeiger f&uuml;r Adresse der Lokomotive</TD></TR>
<TR><TH NOWRAP>DirectionType *Direction</TH><TD>Zeiger f&uuml;r Fahrtrichtung</TD></TR>
<TR><TH NOWRAP>unsigned *Speed</TH><TD>Zeiger f&uuml;r Geschwindigkeit</TD></TR>
</TABLE></TD>
</TR>
</TABLE>
</BODY>
</HTML>
